/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.cheln.explorer.func.setup;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import cn.cheln.explorer.beans.AppInfoData;
import cn.cheln.explorer.beans.ReportInfo;
import cn.cheln.explorer.config.Constants;
import cn.cheln.support.images.Utillocal;
import cn.cheln.support.log.Logs;
import cn.cheln.support.notification.NotifyUtil;
import cn.power.shine.R;

import com.direction.hold.VPAty;
import com.direction.hold.ui.CommonActivity;
import com.direction.hold.ui.CountActivity;
import com.direction.hold.ui.PathActivity;
import com.direction.hold.ui.SlideActivity;

/**
 * @author Administrator
 */
public class PackageInstallManager  {
    public static boolean homeStopFlag;
    public static boolean isInInstall;
    public static ArrayList<String> toInstallPaths;
    private static PackageInstallManager instance;
    public InstallHelper pi;
    NotifyUtil notifyUtil;
    private Context context;
    public int faliureNum = 0;
    public int successNum = 0;
    public int unhandled = 0;
    public Intent backIntent;
    String apkpath;
    String intallingAppLabel;
    public static final String STR_FAIL_APP_LABEL = "failureAppLabels";
    public static boolean shouldStopInstall;
    public boolean renamedFlag = false;
    public static PackageInstallManager createPackageManagerInstance(InstallHelper pi, Context context) {
        if (instance == null) {
            instance = new PackageInstallManager(pi, context);
        }
        return instance;
    }
    public static PackageInstallManager getInstance() {
        return getInstance((Context) (PackageInstallService.context==null?SlideActivity.activity:PackageInstallService.context));
    }
    public static PackageInstallManager getInstance(Context  paraContext) {
        Context context = paraContext!=null?paraContext:VPAty.activity;
        return instance==null||paraContext!=null?createPackageManagerInstance(new InstallHelper(context),context):instance;
    }

    public void endWhileAppAlive() {
        ReportOfInstall.prepareReportText(context);
        popInstallReport();
        notifyAllInstalled(notifyUtil, R.string.totalInstallFinishedHint, successNum, faliureNum,unhandled, pi.getTotalInstallSum(), context, backIntent);
        isInInstall = false;

    }



    public void end(Integer resultAbsId) {
        notifyOverResult(resultAbsId);
        clear();
        NotifyUtil.cancel(VPAty.activity, NotifyUtil.ID_INSTALLED);
        isInInstall = false;
    }

    public String getApkLabel(String apkpath) {
        if (apkpath == null) {
            return null;
        }
        File apk = new File(apkpath);
        AppInfoData appdata = Utillocal.getApkInfo(context, apk);
        String intallingAppLabel;
        if (appdata == null) {
            intallingAppLabel = apk.getName();
        } else {
            intallingAppLabel = appdata.name;
        }
        return intallingAppLabel;
    }

    public void clearHistory() {
        ReportOfInstall.clear();
    }

    public String constructProgress(int current, int total) {
        return " (" + current + "/" + total + ") ";
    }

    protected PackageInstallManager(InstallHelper pi, Context context) {
        this.pi = pi;
        this.context = context;
        notifyUtil = new NotifyUtil(context);
        backIntent = new Intent(Constants.InvokedPath.ACTION_INSTALL_PATH);
        backIntent.addCategory(Intent.CATEGORY_DEFAULT);

    }

    public void notifyOverResult(int resultAbsId) {
        Intent intent = null;
        if (resultAbsId == R.string.install_stoped_by_app_exit) {
            intent = new Intent(Constants.InvokedPath.ACTION_INSTALL_PATH);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
        } else {
            if (VPAty.activity == null) {
            } else {
                intent = new Intent(Constants.InvokedPath.ACTION_INSTALL_PATH);
            }
            intent.addCategory(Intent.CATEGORY_DEFAULT);
        }
        notifyAllInstalled(notifyUtil, resultAbsId, successNum, faliureNum,unhandled, pi.getTotalInstallSum(), context, intent);


    }

    public void notifyOverResult() {
        notifyOverResult(R.string.totalInstallFinishedHint);
    }

    public void packageInstalled(String packageName, int returnCode,boolean failure,String appLabel) {
        if(PackageInstallManager.homeStopFlag){
            return;
        }
        if (shouldStopInstall) {
            shouldStopInstall = false;
            return;
        }
        Logs.i("failureAppLabels ---- packageInstalled " + packageName + " " + returnCode);
        if (pi.getCurrInstallPath() == null) {
            return;
        }
        boolean isFailed = failure;

        if (!isFailed) {

            successNum++;
            unhandled--;
            ReportOfInstall.success.add(new ReportInfo(apkpath, appLabel));
        }
        int isSuccess = !isFailed ? R.string.appInstallSuccessHint : R.string.appInstallFailureHint;

        Logs.i("", "finishedAllInstall ---- apkpath " + apkpath);
        currentSuccess = !isFailed;
        currentTextShow = isSuccess;
        recentLabel = appLabel;
        Logs.e("=== startService PackageInstallService");
        if (tryNextInstall(appLabel, isSuccess, isFailed)) {
            return;
        }
    }
    boolean currentSuccess = false;
    int currentTextShow = -1;
    String recentLabel = "";

    public boolean tryNextInstall(String appLabel, int isSuccess, boolean isFailed) {
        apkpath = pi.getIteratorNext(pi.getPaths());
        Logs.i("", "finishedAllInstall ---- apkpath " + apkpath);
        if (!pi.hasNext(apkpath)) {
            endWhileAppAlive();
        } else {
            String intallingAppLabel = getApkLabel(apkpath);
            tellPreviousInstallationDone(notifyUtil, intallingAppLabel, appLabel, isSuccess, !isFailed, pi.getCurrInstallIdx(), pi.getTotalInstallSum());
            pi.tryInstall(apkpath);
        }
        return false;
    }

    public static class LoaderThread extends HandlerThread implements Handler.Callback {

        private final PackageInstallManager installManager;
        private Handler mLoaderThreadHandler;

        public LoaderThread(PackageInstallManager packageInstallManager) {
            super("");
            this.installManager = packageInstallManager;
        }

        /**
         * Sends a message to this thread to load requested photos.
         */
        public void requestLoading(Message msg) {
            if (mLoaderThreadHandler == null) {
                mLoaderThreadHandler = new Handler(getLooper(), this);
            }
            mLoaderThreadHandler.sendMessage(msg);
        }

        /**
         * Receives the above message, loads photos and then sends a message to
         * the main thread to process them.
         */
        public boolean handleMessage(Message msg) {
            switch (msg.what){
                case 0:
                    final String apkpath = msg.obj.toString();
                    boolean hasnext = installManager.pi.hasNext(apkpath);
                    if (hasnext) {


//                        new Thread(){
//                            @Override
//                            public void run() {
//                                super.run();
                                installManager.pi.tryInstall(apkpath);
                        Message message = new Message();
                        message.what = 1;


                        requestLoading(message);
//                            }
//                        }.start();

                    }
                    break;
                case 1:
                    installManager.tryNextInstall(installManager.recentLabel, installManager.currentTextShow, installManager.currentSuccess);
                    break;
                }

            return false;
        }
    }
    LoaderThread loaderThread;

    List<String> paths = null;
    public void beginInstall(List<String> paths) {
        PackageInstallManager.getInstance().clearHistory();
        PackageInstallManager.getInstance().clear();
        loaderThread = new LoaderThread(this);
        loaderThread.start();
        isInInstall = true;
        unhandled = paths.size();
        this.paths = paths;
        final String apkpath = pi.getIteratorNext(paths);
        intallingAppLabel = getApkLabel(apkpath);
        intallingAppLabel = intallingAppLabel == null || intallingAppLabel.equals(new File(apkpath).getName()) ? context.getString(R.string.unknown) : intallingAppLabel;
        Message msg= new Message();
        msg.what = 0;
        msg.obj = apkpath;
        loaderThread.requestLoading(msg);
//        final PackageInstallManager installManager = this;
//        boolean hasnext = installManager.pi.hasNext(apkpath);
//        if (hasnext) {
//            installManager.beginAllInstall(installManager.notifyUtil, installManager.paths.size(), installManager.intallingAppLabel);
//
//                    installManager.pi.tryInstall(apkpath);
//
//        }
    }

    public void beginAllInstall(NotifyUtil notifyUtil, Integer totalAppNum, String intallingAppLabel,Context context) {
        notifyInstallId(notifyUtil, context.getString(R.string.appInstallStartTicker), context.getString(R.string.installing) + " [" + intallingAppLabel + "] " + constructProgress(1, totalAppNum), context.getString(R.string.nowInstallingForYou), backIntent, context, Service.class);
    }

    private void tellPreviousInstallationDone(NotifyUtil notifyUtil, String intallingAppLabel, String processedAppLabel, int resultLabel, boolean isInstallSuccess, Integer current, Integer totalAppNum) {
        String ticker = processedAppLabel + " " + context.getString(resultLabel);
        String title = context.getApplicationContext().getString(R.string.installing) + " [" + intallingAppLabel + "] " + constructProgress(current, totalAppNum);
        String msg = processedAppLabel + " " + (isInstallSuccess ? context.getString(R.string.already) : "") + context.getString(resultLabel);
        notifyInstallId(notifyUtil, ticker, title, msg, backIntent, VPAty.activity, Activity.class);
    }

    public static void notifyAllInstalled(NotifyUtil notifyUtil, int resulrAbstractId, Integer successNum, Integer failureNum, Integer unhandledNum,Integer totalNum, Context context, Intent backIntent) {
        Logs.i("-----------" + successNum + " " + failureNum + " " + totalNum);
        String successStr = context.getString(R.string.success) + " " + (successNum) + " ";
        String failureStr = context.getString(R.string.failure) + " " + (failureNum) + " ";
        String unhandledStr = context.getString(R.string.unhandled) + " " + (unhandledNum) + " ";
        String totalStr = context.getString(R.string.toInstallSum) + " " + (totalNum);
        String installOverHint = context.getString(resulrAbstractId);
        String messageStr = successStr + " " + failureStr + " "+unhandledStr+" "
                + totalStr;
        String resultAbs = context.getString(resulrAbstractId);
//        if (failureNum > 0) {
//            backIntent.putStringArrayListExtra(STR_FAIL_APP_LABEL, (ArrayList<String>) ReportOfInstall.failed);
//        }
        NotifyUtil.cancel(context,NotifyUtil.ID_INSTALLED);
        notifyInstallId(notifyUtil, resultAbs + "  " + successStr + failureStr + unhandledStr  + totalStr, installOverHint, messageStr, backIntent, VPAty.activity, BroadcastReceiver.class);
    }

    private static void notifyInstallId(NotifyUtil notifyUtil, String tickerText, String title, String downWords, Intent intent, Context activity, Class targetFlag) {
        notifyUtil.notify(NotifyUtil.ID_INSTALLED, R.drawable.com_android_folder, tickerText, title, downWords, intent, activity, targetFlag);
    }

    public void clear() {
        faliureNum = 0;
        successNum = 0;
        unhandled = 0;
    }

    private void popInstallReport() {
        int frameid = SlideActivity.paramActivity.currFrameId;
        CommonActivity ui = null;
        if (frameid == SlideActivity.TAB_INDEX_CATEGORY) {
            ui = CountActivity.categoryActivity;
        } else if (frameid == SlideActivity.TAB_INDEX_SDCARD) {
            ui = PathActivity.activityInstance;
        }
        ui.handler.sendEmptyMessage(Constants.OperationContants.ONINSTALL_REPORT);

    }
}
